﻿using System;
using FreshMeat.Storage;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Storage.Core.Test
{
   [TestClass]
   public class PathTest
   {
      [TestMethod]
      [ExpectedException(typeof(ArgumentNullException))]
      public void AppendWithPath1NullThrows()
      {
         Path.Append(null, "part2");
      }

      [TestMethod]
      [ExpectedException(typeof(ArgumentNullException))]
      public void AppendWithPath2NullThrows()
      {
         Path.Append("part1", null);
      }

      [TestMethod]
      [ExpectedException(typeof(ArgumentException))]
      public void AppendWithAbsolutePath2Throws()
      {
         Path.Append("", "\\part2");
      }

      [TestMethod]
      public void AppendWithPath1EmptyReturnsPath2()
      {
         var result = Path.Append("", "part2");

         Assert.AreEqual("part2", result);
      }

      [TestMethod]
      public void AppendWithPath2EmptyReturnsPath1()
      {
         var result = Path.Append("part1", "");

         Assert.AreEqual("part1", result);
      }

      [TestMethod]
      public void AppendAddsSlash()
      {
         var result = Path.Append("part1", "part2");

         Assert.AreEqual("part1\\part2", result);
      }

      [TestMethod]
      public void AppendDoesntAddSlashWhenItsThere()
      {
         var result = Path.Append("part1\\", "part2");

         Assert.AreEqual("part1\\part2", result);
      }

      [TestMethod]
      public void AppendWorksWithMultiFolderPaths()
      {
         var result = Path.Append("part1\\folder1\\folder2", "part2\\folder1\\folder2");

         Assert.AreEqual("part1\\folder1\\folder2\\part2\\folder1\\folder2", result);
      }

      [TestMethod]
      [ExpectedException(typeof(ArgumentNullException))]
      public void GetLocationNullThrows()
      {
         Path.GetLocation(null);
      }

      [TestMethod]
      public void GetLocationEmptyReturnsEmpty()
      {
         var result = Path.GetLocation("");

         Assert.AreEqual("", result);
      }

      [TestMethod]
      public void GetLocationNoSlashesReturnsEmpty()
      {
         var result = Path.GetLocation("something");

         Assert.AreEqual("", result);
      }

      [TestMethod]
      public void GetLocationOneLeadingSlashReturnsEmpty()
      {
         var result = Path.GetLocation("\\something");

         Assert.AreEqual("", result);
      }

      [TestMethod]
      public void GetLocationLeadingAndOtherSlashesReturnsLocation()
      {
         var result = Path.GetLocation("\\something\\else");

         Assert.AreEqual("\\something", result);
      }

      [TestMethod]
      public void GetLocationTrailingSlashReturnsLocation()
      {
         var result = Path.GetLocation("\\something\\else\\");

         Assert.AreEqual("\\something\\else", result);
      }

      [TestMethod]
      [ExpectedException(typeof(ArgumentNullException))]
      public void GetNameNullThrows()
      {
         Path.GetName(null);
      }

      [TestMethod]
      [ExpectedException(typeof(ArgumentException))]
      public void GetNameEmptyThrows()
      {
         Path.GetName("");
      }

      [TestMethod]
      public void GetNameNoSlashesReturnsName()
      {
         var result = Path.GetName("something");

         Assert.AreEqual("something", result);
      }

      [TestMethod]
      public void GetNameOneLeadingSlashReturnsName()
      {
         var result = Path.GetName("\\something");

         Assert.AreEqual("something", result);
      }

      [TestMethod]
      public void GetNameLeadingAndOtherSlashesReturnsName()
      {
         var result = Path.GetName("\\something\\else");

         Assert.AreEqual("else", result);
      }

      [TestMethod]
      [ExpectedException(typeof(ArgumentException))]
      public void GetNameTrailingSlashThrows()
      {
         Path.GetName("\\something\\else\\");
      }

      [TestMethod]
      [ExpectedException(typeof(ArgumentNullException))]
      public void GetNameWithoutExtensionsNullThrows()
      {
         Path.GetNameWithoutExtensions(null);
      }

      [TestMethod]
      public void GetNameWithoutExtensionsWithNoExtension()
      {
         var result = Path.GetNameWithoutExtensions("\\folder1\\name");

         Assert.AreEqual("name", result);
      }

      [TestMethod]
      public void GetNameWithoutExtensionsWithOneExtension()
      {
         var result = Path.GetNameWithoutExtensions("\\folder1\\name.ext");

         Assert.AreEqual("name", result);
      }

      [TestMethod]
      public void GetNameWithoutExtensionsWithTwoExtensions()
      {
         var result = Path.GetNameWithoutExtensions("\\folder1\\name.ext.xyz");

         Assert.AreEqual("name", result);
      }

      [TestMethod]
      [ExpectedException(typeof(ArgumentNullException))]
      public void GetNameWithoutLastExtensionNullThrows()
      {
         Path.GetNameWithoutLastExtension(null);
      }

      [TestMethod]
      public void GetNameWithoutLastExtensionWithNoExtension()
      {
         var result = Path.GetNameWithoutLastExtension("\\folder1\\name");

         Assert.AreEqual("name", result);
      }

      [TestMethod]
      public void GetNameWithoutLastExtensionWithOneExtension()
      {
         var result = Path.GetNameWithoutLastExtension("\\folder1\\name.ext");

         Assert.AreEqual("name", result);
      }

      [TestMethod]
      public void GetNameWithoutLastExtensionWithTwoExtensions()
      {
         var result = Path.GetNameWithoutLastExtension("\\folder1\\name.ext.xyz");

         Assert.AreEqual("name.ext", result);
      }

      [TestMethod]
      public void GetNameWithoutLastExtensionWithThreeExtensions()
      {
         var result = Path.GetNameWithoutLastExtension("\\folder1\\name.ext.xyz.qrst");

         Assert.AreEqual("name.ext.xyz", result);
      }

      [TestMethod]
      [ExpectedException(typeof(ArgumentNullException))]
      public void RenameWithPathNullThrows()
      {
         Path.Rename(null, "that");
      }

      [TestMethod]
      [ExpectedException(typeof(ArgumentNullException))]
      public void RenameWithNameNullThrows()
      {
         Path.Rename("this", null);
      }

      [TestMethod]
      public void RenameWithNoPathWorks()
      {
         var result = Path.Rename("", "that");

         Assert.AreEqual("that", result);
      }

      [TestMethod]
      public void RenameWithNoNewNameWorks()
      {
         var result = Path.Rename("this", "");

         Assert.AreEqual("", result);
      }

      [TestMethod]
      public void RenameWithTwoNamesWorks()
      {
         var result = Path.Rename("this", "that");

         Assert.AreEqual("that", result);
      }

      [TestMethod]
      public void RenameWithAbsoluteFoldersAndNameWorks()
      {
         var result = Path.Rename("\\folder1\\folder2\\this", "that");

         Assert.AreEqual("\\folder1\\folder2\\that", result);
      }

      [TestMethod]
      public void RenameWithRelativeFoldersAndNameWorks()
      {
         var result = Path.Rename("folder1\\folder2\\this", "that");

         Assert.AreEqual("folder1\\folder2\\that", result);
      }
   }
}
